﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CLVisionTcpIP
{
    public class CLTcpServer
    {
        private TcpListener _listener;
        private bool _isRunning;
        public readonly Dictionary<string, ClientHandler> Clients = new Dictionary<string, ClientHandler>();
        private readonly object _lock = new object();
        private readonly Dictionary<string, ClientMessage> _clientMessages = new Dictionary<string, ClientMessage>();

        public Action<string> OnMessageReceived;
        public Action<string> OnClientConnected;
        public Action<string> OnClientDisConnected;


        public bool Start(out int ErrorCode, out string ErrorText, string ipString = "127.0.0.1", int port = 502)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                _listener = new TcpListener(IPAddress.Parse(ipString), port);
                _listener.Start();
                _isRunning = true;

               new Thread(AcceptClients) { IsBackground = true }.Start();
                //OnMessageReceived("服务器已启动，等待客户端连接...");
                return true;

            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = ex.Message;
                return false;
            }
        }

        private void AcceptClients()
        {
            while (_isRunning)
            {
                try
                {
                    var client = _listener.AcceptTcpClient();

                    var handler = new ClientHandler(client, this);

                    lock (_lock)
                    {
                        Clients.Add(handler.RemoteEndPoint, handler);
                        _clientMessages[handler.RemoteEndPoint] = new ClientMessage();
                    }


                    handler.Start();
                }
                catch { }
            }
        }

        public void RemoveClient(string clientRemoteEndPoint)
        {
            Clients.TryGetValue(clientRemoteEndPoint, out var handler);
            lock (_lock)
            {
                handler.Close();
                Clients.Remove(handler.RemoteEndPoint);
                _clientMessages.Remove(handler.RemoteEndPoint);
            }
            //OnClientDisConnected(handler.RemoteEndPoint);
            //OnMessageReceived($"客户端 {handler.RemoteEndPoint} 已断线。");
        }

        public void SendToAll(string message, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                lock (_lock)
                {
                    foreach (var handler in Clients.Values)
                    {
                        handler.Send(message);
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = ex.Message;
            }
        }

        public void SendToClient(string clientRemoteEndPoint, string message)
        {
            lock (_lock)
            {
                if (Clients.TryGetValue(clientRemoteEndPoint, out var handler))
                {
                    handler.Send(message);
                }
            }
        }

        public void Stop()
        {
            _isRunning = false;
            Thread.Sleep(500);
            try
            {
                _listener?.Stop();
            }
            catch { }

            lock (_lock)
            {
                foreach (var handler in Clients.Values)
                {
                    try
                    {
                        handler.Close();
                    }
                    catch { }
                }
                Clients.Clear();
                _clientMessages.Clear();
            }
            //OnMessageReceived?.Invoke("服务器已关闭。");
        }

        // 存储客户端消息的数据结构
        public class ClientMessage
        {
            public Guid ClientId { get; set; }
            public string Message { get; set; }
            public DateTime Timestamp { get; set; }
            public bool IsHeartbeat { get; set; }
        }

        // 新增：获取客户端的最后一条消息
        public void GetLastClientMessage(string clientRemoteEndPoint, List<ClientMessage> lastMessages, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                lock (_lock)
                {
                    _clientMessages.TryGetValue(clientRemoteEndPoint, out var message);
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = ex.Message;
            }

        }

        // 新增：获取所有客户端的最后一条消息
        public void GetAllLastMessages(List<ClientMessage> lastMessages, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                lock (_lock)
                {
                    lastMessages.Clear();
                    lastMessages.AddRange(_clientMessages.Values);
                    _clientMessages.Clear();
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = ex.Message;
            }
        }

        public class ClientHandler
        {
            private readonly TcpClient _client;
            private readonly CLTcpServer _server;
            private readonly NetworkStream _stream;
            private readonly Thread _thread;
            private DateTime _lastHeartbeat;
            public Guid Id { get; } = Guid.NewGuid();
            public string RemoteEndPoint { get; }


            public ClientHandler(TcpClient client, CLTcpServer server)
            {
                _client = client;
                _server = server;
                _stream = client.GetStream();
                _thread = new Thread(HandleClient) { IsBackground = true };
                //Task.Factory.StartNew(() => { HandleClient(); });
                _lastHeartbeat = DateTime.Now;
                RemoteEndPoint = client.Client.RemoteEndPoint?.ToString();
            }

            public void Start() => _thread.Start();

            private void HandleClient()
            {
                byte[] buffer = new byte[1024*4];
                try
                {
                    while (true)
                    {
                        int bytesRead = _stream.Read(buffer, 0, buffer.Length);
                        if (bytesRead == 0)
                            break;

                        string msg = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                        bool isHeartbeat = msg == "HEARTBEAT";


                        if (isHeartbeat)
                        {
                            _lastHeartbeat = DateTime.Now;
                            byte[] ack = Encoding.UTF8.GetBytes("HEARTBEAT_ACK");
                            _stream.Write(ack, 0, ack.Length);
                        }
                        else
                        {
                            //Console.WriteLine($"收到客户端 {Id} 消息: {msg}");
                            //string response = $"服务器收到: {msg}";
                            UpdateLastMessage(msg, isHeartbeat);
                            //byte[] responseBytes = Encoding.UTF8.GetBytes(response);
                            //_stream.Write(responseBytes, 0, responseBytes.Length);
                        }
                    }
                }
                catch { }
                finally
                {
                    //_server.RemoveClient(this.RemoteEndPoint);
                   // _client.Close();
                }
            }

            // 修改：更新客户端的最后一条消息

            private void UpdateLastMessage(string message, bool isHeartbeat)
            {
                var clientMessage = new ClientMessage
                {

                    ClientId = Guid.NewGuid(),
                    Message = message,
                    Timestamp = DateTime.Now,
                    IsHeartbeat = isHeartbeat
                };

                lock (_server._lock)
                {
                    _server._clientMessages[RemoteEndPoint] = clientMessage;
                }
            }
            public void Send(string message)
            {
                if (_client.Connected)
                {
                    byte[] data = Encoding.UTF8.GetBytes(message);
                    try
                    {
                        _stream.Write(data, 0, data.Length);
                    }
                    catch
                    {
                        // 发送失败可做日志或断线处理
                    }
                }
            }

            public void Close()
            {
                try
                {
                    _client.Close();
                }
                catch { }
            }
        }
    }
}